//
//  TopSongsViewController.m
//  iTunesTopSongs
//
//  Created by 云天 李 on 12-2-18.
//  Copyright (c) 2012年 __MyCompanyName__. All rights reserved.
//

#import "TopSongsViewController.h"
#import "SongDetailViewController.h"
#import "Song.h"
#import "SongCell.h"

@implementation TopSongsViewController

@synthesize songDetailViewController = _songDetailViewController;
@synthesize fetchedResultsController = __fetchedResultsController;
@synthesize managedObjectContext = __managedObjectContext;

@synthesize imageDownloadsInProgress = _imageDownloadsInProgress;
@synthesize songs = _songs;

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
		self.title = NSLocalizedString(@"Top Songs", @"Top Songs");
    }
    return self;
}

- (void)dealloc
{
	// 通知中心移除托管对象上下文相关的通知
	// 这个通知在- (void)viewDidLoad 方法中进行了注册
	[[NSNotificationCenter defaultCenter] removeObserver:self name:NSManagedObjectContextDidSaveNotification object:self.managedObjectContext];
	
	[_songDetailViewController release];
	[__fetchedResultsController release];
	[__managedObjectContext release];
	[_imageDownloadsInProgress release];
	
    [super dealloc];
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Release any cached data, images, etc that aren't in use.
}

#pragma mark - View lifecycle

- (void)viewDidLoad
{
    [super viewDidLoad];
	// Do any additional setup after loading the view, typically from a nib.
	
	// self.managedObjectContext 发出一个通知 NSManagedObjectContextDidSaveNotification 给观察者 self。
	// 并由 self 的方法 handleSaveNotification: 来处理这个通知
	// 意思是，self.managedObjectContext已经把数据保存了，handleSaveNotification:方法继续做一下步吧。
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleSaveNotification:) name:NSManagedObjectContextDidSaveNotification object:self.managedObjectContext];
	
    self.navigationItem.hidesBackButton = YES;
	
    [self fetch];
}

- (void)viewDidUnload
{
    [super viewDidUnload];
    // Release any retained subviews of the main view.
    // e.g. self.myOutlet = nil;
	
	// 通知中心移除托管对象上下文相关的通知
	// 这个通知在- (void)viewDidLoad 方法中进行了注册
	[[NSNotificationCenter defaultCenter] removeObserver:self name:NSManagedObjectContextDidSaveNotification object:self.managedObjectContext];
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    // Return YES for supported orientations
	return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
}

#pragma mark - 下载封面图
// 准备下载
- (void)startImageDownload:(Song *)song forIndexPath:(NSIndexPath *)indexPath
{
    ImageDownloader *imageDownloader = [self.imageDownloadsInProgress objectForKey:indexPath];
    if (imageDownloader == nil) 
    {
        imageDownloader = [[ImageDownloader alloc] init];
        imageDownloader.song = song;
        imageDownloader.indexPathInTableView = indexPath;
        imageDownloader.delegate = self;
        [self.imageDownloadsInProgress setObject:imageDownloader forKey:indexPath];
        [imageDownloader startDownload];
        [imageDownloader release];   
    }
}

// 滚动后，如果当前显示的行没有图片的话，便调用此方法下载图片
- (void)loadImagesForOnscreenRows
{	
    if (self.songs > 0)
    {
        NSArray *visiblePaths = [self.tableView indexPathsForVisibleRows];
        for (NSIndexPath *indexPath in visiblePaths)
        {
            Song *song = [self.fetchedResultsController objectAtIndexPath:indexPath];
            
            // 避免重复下载
            if (!song.coverImage)
            {
                [self startImageDownload:song forIndexPath:indexPath];
            }
        }
    }
}

// 当某个图片下载后，便调用此方法来显示图片
- (void)imageDidLoad:(NSIndexPath *)indexPath
{
    ImageDownloader *imageDownloader = [self.imageDownloadsInProgress objectForKey:indexPath];
    if (imageDownloader != nil)
    {
        SongCell *cell = (SongCell *)[self.tableView cellForRowAtIndexPath:imageDownloader.indexPathInTableView];
        
        // 显示刚才下载的图片
        cell.cover.image = imageDownloader.song.coverImage;
    }
}

// Customize the number of sections in the table view.
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
	return [[self.fetchedResultsController sections] count];
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
	id <NSFetchedResultsSectionInfo> sectionInfo = [[self.fetchedResultsController sections] objectAtIndex:section];
	return [sectionInfo numberOfObjects];
}

// 自定义单元格
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"CustomSongCell";
    
    SongCell *cell = (SongCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil)
	{
		cell = [[[NSBundle mainBundle] loadNibNamed:@"SongCell" owner:self options:nil] lastObject];
	}
	
    Song *song = [self.fetchedResultsController objectAtIndexPath:indexPath];
    cell.title.text = song.title;
	cell.album.text = song.album;
	cell.artist.text = song.artist;
	cell.category.text = song.category;
	cell.rank.text = [NSString stringWithFormat:@"#%d", [song.rank integerValue]];
	
	// 封面图片路径
	NSString *coverPath = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:[song.coverArt lastPathComponent]];
	
	// 检查歌曲封面是否存在
	BOOL fileExisted = [[NSFileManager defaultManager] fileExistsAtPath: coverPath];
	if (fileExisted)
	{
		// 如果歌曲封面存在则显示
		[[cell cover] setImage:[[UIImage alloc] initWithContentsOfFile:coverPath]];
	}
	else
	{
		// 如果歌曲封面不存在
		// 如果没有拖放UITableView
		// 如果UITableView没有在运动（拖放后，抬起手指，UITableView会在惯性下继续运动，直至停止）
		if (self.tableView.dragging == NO && self.tableView.decelerating == NO)
		{
			[self startImageDownload:song forIndexPath:indexPath];
		}
	}
	
    return cell;
}

// 点击某行查看歌曲信息
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    if (!self.songDetailViewController) {
        self.songDetailViewController = [[[SongDetailViewController alloc] initWithNibName:@"SongDetailViewController" bundle:nil] autorelease];
    }
	
    self.songDetailViewController.song = [self.fetchedResultsController objectAtIndexPath:indexPath];
	[self.navigationController pushViewController:self.songDetailViewController animated:YES];
}

// 行高
- (CGFloat)tableView:(UITableView *)atableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
	return 104;
}

#pragma mark - Fetched results controller

- (void)handleSaveNotification:(NSNotification *)aNotification {
    [self.managedObjectContext mergeChangesFromContextDidSaveNotification:aNotification];
    [self fetch];
}

// 从Core Data中获取歌曲信息
- (void)fetch {
    NSError *error = nil;
    BOOL success = [self.fetchedResultsController performFetch:&error];
    NSAssert2(success, @"Unhandled error performing fetch at MasterViewController.m, line %d: %@", __LINE__, [error localizedDescription]);
    [self.tableView reloadData];
	
	// 设置标题
	id <NSFetchedResultsSectionInfo> sectionInfo = [[self.fetchedResultsController sections] objectAtIndex:0];
	self.title = [NSString stringWithFormat:NSLocalizedString(@"Top %d songs", @"Top %d songs"), [sectionInfo numberOfObjects]];
	
	self.songs = [sectionInfo numberOfObjects];
}

- (NSFetchedResultsController *)fetchedResultsController
{
	if (__fetchedResultsController == nil) {
        NSFetchRequest *fetchRequest = [[[NSFetchRequest alloc] init] autorelease];
        [fetchRequest setEntity:[NSEntityDescription entityForName:@"Song" inManagedObjectContext:self.managedObjectContext]];
        NSArray *sortDescriptors = [NSArray arrayWithObject:[[[NSSortDescriptor alloc] initWithKey:@"rank" ascending:YES] autorelease]];
        [fetchRequest setSortDescriptors:sortDescriptors];
        __fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:self.managedObjectContext sectionNameKeyPath:nil cacheName:nil];
    }    
    return __fetchedResultsController;
	
}

#pragma mark -
#pragma mark Deferred image loading (UIScrollViewDelegate)

// 停止拖放后，当UITableView不再运动，才会加载当前屏幕内歌曲的封面
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
{
    if (!decelerate)
	{
        [self loadImagesForOnscreenRows];
    }
}

// 当UITableView停止运动，才会加载当前屏幕内歌曲的封面
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
    [self loadImagesForOnscreenRows];
}

@end
